package com.corpgovernment.travelstandard.impl;

import com.corpgovernment.api.operatelog.chooseconstant.ChooseBusinesstype;
import com.corpgovernment.api.operatelog.soa.OperateLogClient;
import com.corpgovernment.api.operatelog.soa.request.AddOperateLogRequestVo;
import com.corpgovernment.api.operatelog.util.OperateLogContentUtil;
import com.corpgovernment.api.operatelog.vo.OperateLogContentDataVo;
import com.corpgovernment.api.travelstandard.vo.MbTravelstandReasonCodeVo;
import com.corpgovernment.common.apollo.OrganizationApollo;
import com.corpgovernment.common.base.AbstractBaseService;
import com.corpgovernment.common.base.BaseUserInfo;
import com.corpgovernment.common.entity.db.BaseEntity;
import com.corpgovernment.common.utils.ExecutorUtil;
import com.ctrip.corp.obt.generic.utils.JsonUtils;
import com.ctrip.corp.obt.generic.utils.JsonUtils;
import com.corpgovernment.redis.cache.UserCacheManager;
import com.ctrip.corp.obt.generic.core.context.UserInfoContext;
import com.ctrip.corp.obt.generic.utils.CollectionUtils;
import com.ctrip.corp.obt.generic.utils.JsonUtils;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;

@Service
@Slf4j
public class TravelStandardBaseService extends AbstractBaseService {
    @Autowired
    private OperateLogClient operateLogService;
    @Autowired
    private UserCacheManager userCacheManager;
    @Autowired
    private OrganizationApollo organizationApollo;
    @Autowired
    private MbTravelstandReasonCodeService travelstandReasonCodeService;

    protected void insertOperateLog(BaseEntity baseEntity) {
        try {
            //BaseUserInfo baseUserInfo = userCacheManager.getBaseUserInfo();
            BaseUserInfo baseUserInfo = UserInfoContext.getContextParams(BaseUserInfo.class);
            ExecutorUtil.logExecutor.execute(() -> {
                if (baseUserInfo != null) {
                    AddOperateLogRequestVo addOperateLogRequestVo = new AddOperateLogRequestVo();
                    String businessId = String.valueOf(baseEntity.getId());
                    try {
                        List<OperateLogContentDataVo> operateLogContentDataVos = OperateLogContentUtil.toContent(null, baseEntity);
                        operateLogService.addOperateLog(OperateLogContentUtil.toAddOperateLog(baseUserInfo, businessId, addOperateLogRequestVo,
                                operateLogContentDataVos, ChooseBusinesstype.TRAVELCONFIG));
                    } catch (Exception ex) {
                        log.error("organizationManageLog",
                                String.format("新增操作日志错误：[%s][%s]", JsonUtils.toJsonString(addOperateLogRequestVo), ex.getMessage()), null);
                    }
                }
            });
        } catch (Exception ex) {
            log.error("organizationManageLog",
                    String.format("新增操作日志线程错误：[%s]", ex.getMessage()), null);
        }
    }

    protected void updateOperateLog(BaseEntity oldValue, BaseEntity newValue) {
        try {
            //BaseUserInfo baseUserInfo = userCacheManager.getBaseUserInfo();
            BaseUserInfo baseUserInfo = UserInfoContext.getContextParams(BaseUserInfo.class);
            ExecutorUtil.logExecutor.execute(() -> {
                if (baseUserInfo != null) {
                    AddOperateLogRequestVo addOperateLogRequestVo = new AddOperateLogRequestVo();
                    String businessId = String.valueOf(oldValue.getId());
                    try {
                        List<OperateLogContentDataVo> operateLogContentDataVos = OperateLogContentUtil.toContent(oldValue, newValue);
                        operateLogService.addOperateLog(OperateLogContentUtil.toAddOperateLog(baseUserInfo, businessId, addOperateLogRequestVo,
                                operateLogContentDataVos, ChooseBusinesstype.TRAVELCONFIG));
                    } catch (Exception ex) {
                        log.error("organizationManageLog",
                                String.format("差标更新操作日志错误：[%s][%s]", JsonUtils.toJsonString(addOperateLogRequestVo), ex.getMessage()), null);
                    }
                }
            });
        } catch (Exception ex) {
            log.error("organizationManageLog",
                    String.format("差标更新操作日志线程错误：[%s]", ex.getMessage()), null);
        }
    }

    protected void deleteOperateLog(String id) {
        try {
            //BaseUserInfo baseUserInfo = userCacheManager.getBaseUserInfo();
            BaseUserInfo baseUserInfo = UserInfoContext.getContextParams(BaseUserInfo.class);
            ExecutorUtil.logExecutor.execute(() -> {
                if (baseUserInfo != null) {
                    AddOperateLogRequestVo addOperateLogRequestVo = new AddOperateLogRequestVo();
                    try {
                        List<OperateLogContentDataVo> operateLogContentDataVos = Lists.newArrayList(OperateLogContentDataVo.logicDelete());
                        operateLogService.addOperateLog(OperateLogContentUtil.toAddOperateLog(baseUserInfo, id, addOperateLogRequestVo,
                                operateLogContentDataVos, ChooseBusinesstype.TRAVELCONFIG));
                    } catch (Exception ex) {
                        log.error("organizationManageLog",
                                String.format("差标删除日志错误：[%s][%s]", JsonUtils.toJsonString(addOperateLogRequestVo), ex.getMessage()), null);
                    }
                }
            });
        } catch (Exception ex) {
            log.error("organizationManageLog",
                    String.format("差标删除日志线程错误：[%s]", ex.getMessage()), null);
        }
    }

    protected void deleteOperateLog(BaseEntity oldValue, BaseEntity newValue) {
        try {
            //BaseUserInfo baseUserInfo = userCacheManager.getBaseUserInfo();
            BaseUserInfo baseUserInfo = UserInfoContext.getContextParams(BaseUserInfo.class);
            ExecutorUtil.logExecutor.execute(() -> {
                if (baseUserInfo != null) {
                    AddOperateLogRequestVo addOperateLogRequestVo = new AddOperateLogRequestVo();
                    String businessId = String.valueOf(oldValue.getId());
                    try {
                        List<OperateLogContentDataVo> operateLogContentDataVos = OperateLogContentUtil.deleteToContent(oldValue, newValue);
                        operateLogService.addOperateLog(OperateLogContentUtil.toAddOperateLog(baseUserInfo, businessId, addOperateLogRequestVo,
                                operateLogContentDataVos, ChooseBusinesstype.TRAVELCONFIG));
                    } catch (Exception ex) {
                        log.error("organizationManageLog",
                                String.format("差标删除操作日志错误：[%s][%s]", JsonUtils.toJsonString(addOperateLogRequestVo), ex.getMessage()), null);
                    }
                }
            });
        } catch (Exception ex) {
            log.error("organizationManageLog",
                    String.format("差标删除操作日志线程错误：[%s]", ex.getMessage()), null);
        }
    }

    /**
     * 插入RC原因
     *
     * @param rcKeys
     * @param travelstandId
     */
    protected void insertTravelstandReasonCode(String[] rcKeys, Long travelstandId) {

        //从apollo获取默认RC并插入
        for (String key : rcKeys) {

            Map rcTemplate = JsonUtils.parseMap(organizationApollo.getAllProductRcReasonTemplate());
            if (rcTemplate == null) {
                return;
            }
            Object obj = rcTemplate.get(key);
            if (obj == null) {
                return;
            }
            List<MbTravelstandReasonCodeVo> travelstandReasonCodeVosFc = JsonUtils.parseArray(JsonUtils.toJsonString(obj), MbTravelstandReasonCodeVo.class);
            if (CollectionUtils.isEmpty(travelstandReasonCodeVosFc)) {
                return;
            }

            //批量插入RC信息
            for (MbTravelstandReasonCodeVo travelstandReasonCodeVo : travelstandReasonCodeVosFc) {
                travelstandReasonCodeVo.setTsId(travelstandId);
                log.info("批量插入RC信息{}", travelstandReasonCodeVo);
                travelstandReasonCodeService.insert(travelstandReasonCodeVo);
            }
        }
    }
}
